package com.zztl.infiniteBand.ui.activity

import android.app.ActivityManager
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothGatt
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.CountDownTimer
import android.os.Handler
import android.util.Log
import android.view.View
import butterknife.OnClick
import com.clj.fastble.BleManager
import com.clj.fastble.callback.BleConnectCallback
import com.clj.fastble.data.BleDevice
import com.clj.fastble.exception.BleException
import com.clj.fastble.scan.BleScanRuleConfig
import com.zztl.infiniteBand.R
import com.zztl.infiniteBand.base.BaseMvpActivity
import com.zztl.infiniteBand.eventbus.FirmwareUpdateEvent
import com.zztl.infiniteBand.net.imp.DownLoadListener
import com.zztl.infiniteBand.presenter.DownLoadFilePresenter
import com.zztl.infiniteBand.service.DfuService
import com.zztl.infiniteBand.ui.view.dialog.LoadingDialog
import com.zztl.infiniteBand.ui.view.mvpview.MvpView
import com.zztl.infiniteBand.util.LogUtils
import com.zztl.infiniteBand.util.PermissionUtils
import com.zztl.infiniteBand.util.device.DeviceUtil
import com.zztl.infiniteBand.util.device.FindDeviceCallback
import com.zztl.infiniteBand.util.toast
import kotlinx.android.synthetic.main.activity_firmware_update.*
import no.nordicsemi.android.dfu.DfuProgressListener
import no.nordicsemi.android.dfu.DfuServiceInitiator
import no.nordicsemi.android.dfu.DfuServiceListenerHelper
import org.greenrobot.eventbus.EventBus


class FirmwareUpdateActivity : BaseMvpActivity<MvpView, DownLoadFilePresenter>(), MvpView {


    lateinit var mPresenter: DownLoadFilePresenter
    private var url: String? = null
    private val mHandler by lazy {
        Handler()
    }
    val TAG: String = "FirmwareUpdateActivity"
    private var mLoadingDialog: LoadingDialog? = null
    private var selectedMac: String? = null

    lateinit var mCountDownTimer: CountDownTimer

    override fun setLayoutId(): Int = R.layout.activity_firmware_update

    override fun initBase() {
        setTitle(getString(R.string.固件升级))
        url = intent.getStringExtra("downUrl")
        mCountDownTimer = object : CountDownTimer(1000 * 15, 1000) {
            override fun onTick(millisUntilFinished: Long) {
            }

            override fun onFinish() {
                DeviceUtil.stopScan()
            }
        }
//        BraceletApplication.zhBraceletService?.addConnectorListener(this)
    }

    override fun createPresenter(): DownLoadFilePresenter {
        return DownLoadFilePresenter().apply {
            mPresenter = this
        }
    }

    override fun onResume() {
        super.onResume()
        DfuServiceListenerHelper.registerProgressListener(this, mDfuProgressListener)
    }

    override fun onPause() {
        super.onPause()
        DfuServiceListenerHelper.unregisterProgressListener(this, mDfuProgressListener)
    }


    private val mDfuProgressListener = object : DfuProgressListener {
        override fun onDeviceConnecting(deviceAddress: String) {
            Log.e(TAG, "onDeviceConnecting")
        }

        override fun onDeviceConnected(deviceAddress: String) {
            Log.e(TAG, "onDeviceConnected")
        }

        override fun onDfuProcessStarting(deviceAddress: String) {

            progress_view.setProgress(50)
            tv_hint.text = getString(R.string.正在升级请稍后)
            Log.e(TAG, "onDfuProcessStarting")
        }

        override fun onDfuProcessStarted(deviceAddress: String) {

            Log.e(TAG, "onDfuProcessStarted")
        }

        override fun onEnablingDfuMode(deviceAddress: String) {
            Log.e(TAG, "onEnablingDfuMode")
        }

        override fun onProgressChanged(deviceAddress: String, percent: Int, speed: Float, avgSpeed: Float, currentPart: Int, partsTotal: Int) {
            Log.e(TAG, "onProgressChanged$percent")
            progress_view.setProgress(percent / 2 + 50)

        }

        override fun onFirmwareValidating(deviceAddress: String) {
            Log.e(TAG, "onFirmwareValidating")
        }

        override fun onDeviceDisconnecting(deviceAddress: String) {

            Log.e(TAG, "onDeviceDisconnecting")
        }

        override fun onDeviceDisconnected(deviceAddress: String) {
            Log.e(TAG, "onDeviceDisconnected")
            progress_view.setProgress(0)
            stopDfu()
        }

        override fun onDfuCompleted(deviceAddress: String) {
            Log.e(TAG, "onDfuCompleted")
            btn_upgrade.isClickable = true
            tv_hint.text = getString(R.string.固件升级完成)

            showLoadingDialog()
            EventBus.getDefault().post(FirmwareUpdateEvent())
            mHandler.postDelayed({
               /* BraceletApplication.zhBraceletService?.apply {
                    selectedMac?.let {
                        connectDevice(it)
                    }
                }*/
                selectedMac?.run {
                    BleManager.getInstance().connect(this,object :BleConnectCallback(){
                        override fun onStartConnect() {
                            TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
                        }

                        override fun onConnectFail(bleDevice: BleDevice?, exception: BleException?) {
                            toast(getString(R.string.请重新连接设备))
                            finish()
                        }

                        override fun onConnectSuccess(bleDevice: BleDevice?, gatt: BluetoothGatt?, status: Int) {
                            finish()
                        }

                        override fun onDisConnected(isActiveDisConnected: Boolean, device: BleDevice?, gatt: BluetoothGatt?, status: Int) {
                            TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
                        }
                    })
                }

            }, 1000)


        }

        override fun onDfuAborted(deviceAddress: String) {
            Log.e(TAG, "onDfuAborted")

            //           ToastUtils.show(FirmwareUpgradeActivity.this,getString(R.string.由于网络异常升级失败));
        }

        override fun onError(deviceAddress: String, error: Int, errorType: Int, message: String) {
            Log.e(TAG, "onError------$deviceAddress---errpr==$error--errorType==$errorType------message==$message")
            btn_upgrade.isClickable = true
            progress_view.setProgress(0)
            tv_hint.text = getString(R.string.更新失败请重试)
            toast(getString(R.string.更新失败请重试))
            stopDfu()

        }
    }




    @OnClick(R.id.btn_upgrade)
    fun click() {
        url?.let {

            PermissionUtils.requestMultiPermissions(this, mPermissionGrant, PermissionUtils.CODE_LOAD_FILE)
        }

    }


    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
                                            grantResults: IntArray) {
        PermissionUtils.requestPermissionsResult(this, requestCode, permissions, grantResults, mPermissionGrant)

    }


    private val mPermissionGrant = object : PermissionUtils.PermissionGrant {
        override fun onPermissionGranted(requestCode: Int) {
            when (requestCode) {
                PermissionUtils.CODE_MULTI_PERMISSION -> {
                    btn_upgrade.isClickable = false
                    mPresenter.downLoad(url!!, "ota.zip", mLoadListener)
                }
            }

        }
    }


    private val mLoadListener = object : DownLoadListener {
        override fun startLoad() {

            tv_hint.visibility = View.VISIBLE
            tv_hint.text = getString(R.string.正在下载固件包请稍后)

        }

        override fun onPregress(progress: Int) {
            runOnUiThread {
                progress_view.setProgress(progress / 2)
            }

        }

        override fun loadFinish() {
            Log.i(TAG, "下载完成------------------")

            update()

        }

        override fun loadError(errorInfo: String) {

            btn_upgrade.isClickable = true

        }
    }


    /**
     * 发送dfu指令
     */
    fun update() {
        LogUtils.i(TAG, "发送dfu指令-----------" + DeviceUtil.getConnectedMac())
        DeviceUtil.getConnectedMac().let {
            if (it.isNotEmpty()) {
              BleManager.getInstance().dataComonent.intoUpdate()
                LogUtils.i(TAG, "发送dfu指令-----------")
                BleScanRuleConfig.Builder().setAutoConnect(false).setDeviceName(true, BleManager.WATCH_NAME).build().apply {
                    BleManager.getInstance().initScanRule(this)
                }
                mHandler.postDelayed({
                    DeviceUtil.scan(object : FindDeviceCallback {
                        override fun findDevice(device: BluetoothDevice) {
                            LogUtils.i(TAG, "device--------------" + device.name + "--------" + device.address)
                            if (device.address.substring(0, 14) == it.substring(0, 14)) {
                                BleManager.getInstance().stopScan()
                                selectedMac = it
                                startOTA(device.address, device.name)
                            }
                        }
                    })
                }, 2000)

            }
        }
//        BleManager.getInstance().connecredDevice.mac.let {  }

    }

    private fun startOTA(address: String, name: String) {
        val enablePRNs = Build.VERSION.SDK_INT < Build.VERSION_CODES.M

                if (isDfuServiceRunning()) {
                    return
                }
                DfuServiceInitiator(address)
                        .setDeviceName(name)
                        .setDisableNotification(true)
                        .setUnsafeExperimentalButtonlessServiceInSecureDfuEnabled(true)
                        .setZip(null, "/sdcard/InfiniteBand/ota.zip")
                        .start(this@FirmwareUpdateActivity, DfuService::class.java)



    }


    //DFU 是否开启
    private fun isDfuServiceRunning(): Boolean {
        val manager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        for (service in manager.getRunningServices(Integer.MAX_VALUE)) {
            if (DfuService::class.java!!.getName() == service.service.className) {
                return true
            }
        }
        return false
    }

    private fun stopDfu() {
        val intent = Intent(this, DfuService::class.java)
        stopService(intent)

    }


    private fun showLoadingDialog() {
        mLoadingDialog ?: kotlin.run {
            mLoadingDialog = LoadingDialog.Builder(this)
                    .setShowMessage(true)
                    .setMessage(getString(R.string.设备连接中请稍后))
                    .setCancelable(true).create()
        }
        mLoadingDialog?.show()
    }

    override fun onDestroy() {
        super.onDestroy()
        mLoadingDialog?.run {
            dismiss()
            null
        }
        stopDfu()
        mHandler.removeCallbacksAndMessages(null)
    }


}



